package com.simen.hellobytes.android.widget;

import android.text.InputFilter;
import android.text.Spanned;

/**
 * 本类长度计算法方式：1个汉字2字节，1字母1字节，特殊表情类4个字节
 * author: simenHi
 * create time: 2020-04-28 17:59
 * description:
 */
public class MaxByteLengthInputFilter implements InputFilter {

    private static final String TAG = LengthFilter.class.getSimpleName();

    public interface onLengthChangeListener {
        void onLengthChange(boolean overMax);
    }

    private int maxByteLength;
    private onLengthChangeListener onLengthChangeListener;

    public MaxByteLengthInputFilter(int maxByteLength) {
        this(maxByteLength, null);
    }

    public MaxByteLengthInputFilter(int maxByteLength, onLengthChangeListener onLengthChangeListener) {
        this.maxByteLength = maxByteLength;
        this.onLengthChangeListener = onLengthChangeListener;
    }

    public static int getByteLength(CharSequence charSequence) {
        int totalLength = 0;
        for (int i = 0; i < charSequence.length(); i++) {
            char c = charSequence.charAt(i);

            if ((int)c < 128) {
                totalLength++;
            } else {
                totalLength += 2;
            }
        }
        return totalLength;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                               int dstart, int dend) {
        //Log.d(TAG, "filter: " + source + " " + start + " " + end + " " + dest + " " + dstart + " " + dend);

        CharSequence preDest = dest.subSequence(0, dstart);
        CharSequence sufferDest = dest.subSequence(dend, dest.length());
        CharSequence appendStr = source.subSequence(start, end);

        //Log.d(TAG, "filter: " + preDest + " " + sufferDest + " " + appendStr + " " + preDest.length() + " " + sufferDest.length() + " " + appendStr.length());

        int keep2 = maxByteLength - getByteLength(preDest) - getByteLength(sufferDest);

        if (keep2 <= 0) {
            //超出范围
            if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(true);
            return "";
        }

        if (keep2 >= getByteLength(appendStr)) {
            //可以输入
            if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(false);
            return null;
        }

        //部分输入,for循环逐字符截取
        for (int i = 0; i < appendStr.length(); i++) {
            if (Character.isHighSurrogate(appendStr.charAt(i))) {
                //每字符视作2个字节
                if (keep2 - 4 < 0) {//高占位单元+低占位单元(下个字符)共4个字节
                    if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(true);
                    return appendStr.subSequence(0, i);
                }
                keep2 -= 4;
                i+=1;//调过低占位单元
            } else if (appendStr.charAt(i) < 128) {
                //每字符视作1个字节
                if (keep2 - 1 < 0) {
                    if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(true);
                    return appendStr.subSequence(0, i);
                }
                keep2 -= 1;
            } else {
                //每字符视作2个字节
                if (keep2 - 2 < 0) {
                    if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(true);
                    return appendStr.subSequence(0, i);
                }
                keep2 -= 2;
            }
        }

        if (onLengthChangeListener != null) onLengthChangeListener.onLengthChange(true);
        return "";
    }

    public void setMaxByteLength(int maxByteLength) {
        this.maxByteLength = maxByteLength;
    }

    /**
     * @return the maximum length enforced by this input filter
     */
    public int getMaxByteLength() {
        return maxByteLength;
    }

}
